package com.eian.boot.module.system.associations.role.permission.listener;

import com.eian.boot.module.system.associations.role.permission.event.PermissionUnassignedEvent;
import com.eian.boot.module.system.associations.role.permission.event.RolePermissionAssignedEvent;
import com.eian.boot.module.system.associations.user.role.service.UserRoleRelationService;
import com.eian.boot.module.system.permission.service.PermissionCacheService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * 角色权限关系事件监听器
 * 处理关系变更后的副作用（如缓存清理）
 *
 * @author alex.meng
 * @since 1.0.0
 */
@Slf4j
@Component
@AllArgsConstructor
public class RolePermissionEventListener {

    private final PermissionCacheService cacheService;
    private final UserRoleRelationService userRoleRelationService;

    /**
     * 监听角色权限分配事件
     * 异步清理角色权限缓存及关联用户缓存
     */
    @Async
    @EventListener
    public void onRolePermissionAssigned(RolePermissionAssignedEvent event) {
        log.debug("处理角色权限分配事件: roleId={}", event.getRoleId());

        // 清除角色权限缓存
        cacheService.clearRolePermissions(event.getRoleId());

        // 清除该角色下所有用户的缓存
        List<Long> userIds = userRoleRelationService.getUserIdsByRoleId(event.getRoleId());
        if (!userIds.isEmpty()) {
            cacheService.clearUserAllCacheBatch(userIds);
        }
    }

    /**
     * 监听权限解绑事件（权限被删除）
     * 异步清理所有关联角色及其用户的缓存
     */
    @Async
    @EventListener
    public void onPermissionUnassigned(PermissionUnassignedEvent event) {
        log.debug("处理权限解绑事件: permissionId={}, affectedRoles={}",
                event.getPermissionId(), event.getRoleIds().size());

        // 清除所有关联角色的权限缓存
        event.getRoleIds().forEach(roleId -> {
            cacheService.clearRolePermissions(roleId);

            // 清除该角色下所有用户的缓存
            List<Long> userIds = userRoleRelationService.getUserIdsByRoleId(roleId);
            if (!userIds.isEmpty()) {
                cacheService.clearUserAllCacheBatch(userIds);
            }
        });
    }
}

